package leetcode.dynamic;

/*

给定一个整数数组，其中第 i 个元素代表了第 i 天的股票价格 。​

设计一个算法计算出最大利润。在满足以下约束条件下，你可以尽可能地完成更多的交易（多次买卖一支股票）:

你不能同时参与多笔交易（你必须在再次购买前出售掉之前的股票）。
卖出股票后，你无法在第二天买入股票 (即冷冻期为 1 天)。
示例:

输入: [1,2,3,0,2]
输出: 3
解释: 对应的交易状态为: [买入, 卖出, 冷冻期, 买入, 卖出]

来源：力扣（LeetCode）
链接：https://leetcode-cn.com/problems/best-time-to-buy-and-sell-stock-with-cooldown
著作权归领扣网络所有。商业转载请联系官方授权，非商业转载请注明出处。

解法：
    1. 动态规划数组dp[i][2]表示的含义
    dp[i][0] 表示在 i 天手中没有股票时的最大利润
    dp[i][1] 表示在 i 天手中持有一只股票时的最大利润

    dp[i][0] = Math.max(dp[i - 1][0], dp[i - 1][1] + prices[i]);// 第 i 天没有交易，或者在i - 1持有股票的情况下在第 i 天卖了
    dp[i][1] = Math.max(dp[i - 1][1], dp[i - 2][0] - prices[i]);// 第 i 天没有交易，或者在第 i 天买入了，因为存在冷却期，所以前一次的卖出操作至少应该在第 i - 2天

 */

public class LeetCode309_MaxProfit {
    public int maxProfit(int[] prices) {

        if (prices.length < 2) return 0;
        if (prices.length == 2) return Math.max(prices[1] - prices[0], 0);
        int[][] dp = new int[prices.length][2];
        dp[0][0] = 0;
        dp[0][1] = -prices[0];

        dp[1][0] = Math.max(prices[1] - prices[0], 0);
        dp[1][1] = -Math.min(prices[0], prices[1]);

        for (int i = 2; i < prices.length; i++){
            dp[i][0] = Math.max(dp[i - 1][0], dp[i - 1][1] + prices[i]);
            dp[i][1] = Math.max(dp[i - 1][1], dp[i - 2][0] - prices[i]);
        }
        return dp[dp.length - 1][0];
    }

    public static void main(String[] args) {
        int[] p = {2, 1, 4};
        int i = new LeetCode309_MaxProfit().maxProfit(p);
        System.out.println("i = " + i);
    }
}
